package com.example.myblog.controller;

import com.example.myblog.common.AjaxResult;
import com.example.myblog.common.GloableVariable;
import com.example.myblog.common.PasswordUtils;
import com.example.myblog.common.UserSessionUtils;
import com.example.myblog.entity.UserInfo;
import com.example.myblog.entity.UserInfoMore;
import com.example.myblog.service.ArticleService;
import com.example.myblog.service.UserService;
import com.example.myblog.service.VerifyService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.UUID;

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private ArticleService articleService;
    @Autowired
    private VerifyService verifyService;


    @RequestMapping("/register")
    public AjaxResult register(@RequestParam("username") String username,
                               @RequestParam("password") String password,
                               @RequestParam("email") String email,
                               @RequestParam("code") String code) {
        if (username.isEmpty()
                || password.isEmpty() || email.isEmpty() || code.isEmpty()) {
            return AjaxResult.fail(-1, "非法参数");
        }
        if (!verifyService.doTextVerify(email, code)) {
            return AjaxResult.fail(-2, "验证码错误");
        }
        UserInfo user1 = userService.getUserByName(username);
        if (user1 != null && !user1.getUsername().isEmpty()) {
            return AjaxResult.fail(-3, "用户名已存在");
        }
        UserInfo user2 = userService.getUserByEmail(email);
        if (user2 != null && !user2.getEmail().isEmpty()) {
            return AjaxResult.fail(-4, "邮箱已注册");
        }
        UserInfo userInfo = new UserInfo();
        String saltPassword = PasswordUtils.encrypt(password);
        userInfo.setUsername(username);
        userInfo.setPassword(saltPassword);
        userInfo.setEmail(email);
        return AjaxResult.success(userService.register(userInfo));
    }

    @RequestMapping("/login")
    public AjaxResult login(HttpServletRequest request,
                            @RequestParam("email") String email,
                            @RequestParam("password") String password,
                            @RequestParam("code") String code) {
        if (!StringUtils.hasLength(email) || !StringUtils.hasLength(password)
                || !StringUtils.hasLength(code)) {
            return AjaxResult.fail(-1, "非法请求");
        }
        HttpSession session = request.getSession();//创建session
        if (!verifyService.doImageVerify(session, code)) {
            return AjaxResult.fail(-2, "验证码错误");
        }
        UserInfo userInfo = userService.getUserByEmail(email);
        if (userInfo != null && userInfo.getId() > 0) {//密码校验
            if (PasswordUtils.check(password, userInfo.getPassword())) {

                session.setAttribute(GloableVariable.USER_SESSION_KEY, userInfo);
                userInfo.setPassword("");//私密信息隐藏
                return AjaxResult.success(userInfo);
            }
        }
        return AjaxResult.success(0, null);
    }

    @RequestMapping("/showinfo")
    public AjaxResult showInfo(HttpServletRequest request) {
        UserInfoMore userInfoMore = new UserInfoMore();
        UserInfo userInfo = UserSessionUtils.getUser(request);
        if (userInfo == null) {
            return AjaxResult.fail(-1, "非法请求");
        }
        BeanUtils.copyProperties(userInfo, userInfoMore);//相同字段深拷贝
        userInfoMore.setArtCount(articleService.getArtCntByUid(userInfoMore.getId()));//获取用户文章发布数
        return AjaxResult.success(userInfoMore);
    }

    @RequestMapping("/logout")
    public AjaxResult logout(HttpSession session) {
        session.removeAttribute(GloableVariable.USER_SESSION_KEY);
        return AjaxResult.success(1);
    }

    @RequestMapping("/getuserbyid")
    public AjaxResult getUserById(Integer id) {
        if (id == null || id <= 0) {
            return AjaxResult.fail(-1, "非法参数");
        }
        UserInfo userInfo = userService.getUserById(id);
        if (userInfo == null || userInfo.getId() <= 0) {
            return AjaxResult.fail(-1, "非法参数");
        }
        userInfo.setPassword("");
        UserInfoMore userInfoMore = new UserInfoMore();
        BeanUtils.copyProperties(userInfo, userInfoMore);
        userInfoMore.setArtCount(articleService.getArtCntByUid(id));
        return AjaxResult.success(userInfoMore);
    }

    @RequestMapping("/getuserbyemail")
    public AjaxResult getUserByEmail(String email) {
        if (email == null || email.isEmpty()) {
            return AjaxResult.fail(-1, "非法参数");
        }
        UserInfo userInfo = userService.getUserByEmail(email);
        if (userInfo == null || userInfo.getId() <= 0) {
            return AjaxResult.fail(-1, "非法参数");
        }
        userInfo.setPassword("");
        UserInfoMore userInfoMore = new UserInfoMore();
        BeanUtils.copyProperties(userInfo, userInfoMore);
        userInfoMore.setArtCount(articleService.getArtCntByUid(userInfo.getId()));
        return AjaxResult.success(userInfoMore);
    }

    @RequestMapping("/getTextCode")
    public void getTextCode(@RequestParam("email") String email) {
        verifyService.getTextCode(email);
    }

    @RequestMapping("/getImageCode")
    public void getImageCode(HttpServletRequest request, HttpServletResponse response) {
        verifyService.getImageCode(request, response);
    }

    @RequestMapping("/update")
    public AjaxResult update(HttpServletRequest request,
                             UserInfo userInfo) {
        if (userInfo == null || !StringUtils.hasLength(userInfo.getUsername())) {
            return AjaxResult.fail(-1, "参数错误");
        }
        UserInfo user = UserSessionUtils.getUser(request);
        if (user == null) {
            return AjaxResult.fail(-2, "用户未登录");
        }
        userInfo.setId(user.getId());
        return AjaxResult.success(userService.update(userInfo));
    }

    @RequestMapping("/uploadphoto")
    public AjaxResult updatePhoto(HttpServletRequest request,
                                  @RequestPart("photo") MultipartFile photo) {
        //非空校验
        if (photo == null) {
            return AjaxResult.fail(403, "图片错误!");
        }
        //要上传的文件名
        String originalFileName = photo.getOriginalFilename();

        //获取用户信息(1.删除旧头像需要原来的旧头像的路径 2.修改图片需要用户 id)
        UserInfo userInfo = UserSessionUtils.getUser(request);
        if (userInfo == null || !StringUtils.hasLength(userInfo.getUsername()) ||
                !StringUtils.hasLength(userInfo.getPassword())) {
            return AjaxResult.fail(403, "参数错误!");
        }
        if (!userInfo.getPhoto().equals("img/default.jpg")) {
            //不是修改默认头像的话就将旧头像删除即可
            File file = new File(GloableVariable.IMG_PATH_ABSOLUTE
                    + userInfo.getPhoto().split("/")[2]);
            file.delete();
        }

        //获取文件后缀
        String suffix = originalFileName.substring(originalFileName.lastIndexOf("."));
        //生成图片名称，使用 UUID 避免相同图片名冲突，加上图片后缀
        String photoName = UUID.randomUUID().toString() + suffix;

        //图片保存路径(绝对路径/相对路径)
        //这里为什么还要用相对路径，只用绝对路径不行么?
        //因为禁止浏览器访问本地磁盘绝对路径路径，因此最简单的办法就是配置一个绝对路径用来保存文件，一个相对路径提供给浏览器访问
        String photoPathAbsolute = GloableVariable.IMG_PATH_ABSOLUTE + photoName; //绝对路径
        String photoPathRelative = GloableVariable.IMG_PATH_RELATIVE + photoName; //相对路径
        //生成文件(绝对路径)
        File saveFile = new File(photoPathAbsolute);
        try {
            //将上传文件绝对路径保存到服务器文件系统
            photo.transferTo(saveFile);
            //保存图片相对路径到数据库中
            userService.updatePhotoById(userInfo.getId(), photoPathRelative);
            //修改评论
//            userInfo.setPhoto(photoPathRelative);
//            updateInfoUtils.updateSessionAndComment(request, userInfo);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //将图片相对路径返回给前端
        return AjaxResult.success(photoPathRelative);
    }
}
